from functools import wraps
import asyncio
import pickle
import random

class myRPCProtocol(asyncio.DatagramProtocol):

    def __init__(self, timeout=10):
        self.timeout = timeout;
        self.requests = {};

        super(myRPCProtocol, self).__init__();
    #实现父类方法-建立连接后回调
    def connection_made(self, transport):
        # print("connetcion setup:",transport);

        self.transport = transport;
        self.socket_addr = self.transport.get_extra_info('sockname');

    def postRequest(self, peer, funcName, *args, **kwargs):
        print("89")
        messageID = "2316545645";

        reply = asyncio.Future();
        self.requests[messageID] = reply;

        loop = asyncio.get_event_loop();
        loop.call_later(self.timeout, self.handletimeout, messageID, peer, args, kwargs);

        obj = ('request', messageID, funcName, args, kwargs);
        message = pickle.dumps(obj, protocol=0);
        self.transport.sendto(message, peer);

        return reply

def convert2RPC(func):
    print("2")
    @asyncio.coroutine
    @wraps(func)
    def convert(*args, **kwargs):
        print("3")
        instance, peer, *args = args;
        response = yield from instance.postRequest(peer, convert.funcName, *args, **kwargs);
        return response

    convert.funcName = func.__name__ ;
    convert.recall_function = func;

    return convert;

class Node(myRPCProtocol):
    @convert2RPC
    def ping(self,peer,peerID):
        print("1")
        print( "handling ping", peer, peerID)
        return (self.ID, peerID)

if __name__ == "__main__":
    node = Node()
    node.ping("127.0.0.1",154)
    

